package cn.tedu.micro.demo.client.demo01;

import cn.tedu.micro.demo.client.RabbitChannelManager;
import com.rabbitmq.client.*;
import org.junit.jupiter.api.Test;

import java.io.IOException;

/**
 * 负责测试监听消费消息
 */
public class Consumer {
    //queue01监听队列 拿到消息消费 手动反序列化 打印
    @Test
    public void consume() throws IOException, InterruptedException {
        Channel channel = RabbitChannelManager.newChannel();
        //lamda表达式 换成匿名内部类 更符合面向对象编程思想.

        /*
           String queue: 消费方法监听的队列名称,不能同时监听两个队列
           Boolean autoAck: 是否自动确认 如果是true 消息在消费之前就确认 在rabbitmq删除
           DeliverCallback deliver: 作用和之前MqttCallback类似,触发调用的时机,就是消息达到
           CancelCallback cancel: 如果消费断开,停止消费,取消回调会被触发
         */
        DeliverCallback deliver=new DeliverCallback() {
            /**
             * 消息到达的消息入口 和messageArrived完全一样的作用
             * @param consumerTag 每个channel监听的时候都会为消费者申请一个标志 全局唯一
             * @param message 传达的消息对象(routingKey,body,props)
             * @throws IOException
             */
            @Override
            public void handle(String consumerTag, Delivery message) throws IOException {
                //1.消息体
                byte[] body = message.getBody();
                String msg=new String(body);
                System.out.println("消息内容:"+msg);
                //2.消息头
                AMQP.BasicProperties props = message.getProperties();
                System.out.println("消息属性:"+props);
                //3.routingKey 消息来源exchange 消息tag(身份)
                String routingKey = message.getEnvelope().getRoutingKey();
                System.out.println("消息路由:"+routingKey);
                //手动确认结果
                channel.basicAck(message.getEnvelope().getDeliveryTag(), false);
            }
        };
        CancelCallback cancel=new CancelCallback(){
            @Override
            public void handle(String consumerTag) throws IOException {
                System.out.println("消费者停止消费");
            }
        };
        channel.basicConsume("queue02",false,
                deliver,
                cancel);
        //为了看到消费处理逻辑打印日志 不能让主线程停止
        Thread.sleep(10000000);
    }
}
